package com.ics.cmsadmin.modules;

import com.ics.cmsadmin.frame.constant.Constants;
import com.ics.cmsadmin.frame.core.bean.ApiResponse;
import com.ics.cmsadmin.frame.core.enums.ApiResultEnum;
import com.ics.cmsadmin.frame.core.exception.CmsException;
import com.ics.cmsadmin.frame.email.MailUtils;
import com.ics.cmsadmin.frame.utils.HttpUtils;
import com.ics.cmsadmin.frame.utils.RedisUtils;
import com.ics.cmsadmin.frame.utils.Tools;
import com.ics.cmsadmin.frame.utils.VelocityUtils;
import com.ics.cmsadmin.modules.auth.bean.SysUser;
import com.ics.cmsadmin.modules.auth.service.UserService;
import com.ics.cmsadmin.modules.sso.LoginInfo;
import com.ics.cmsadmin.modules.sso.handler.CmsAdminWebLoginHandler;
import com.ics.cmsadmin.modules.sso.handler.WechatCodeLoginHandler;
import com.ics.cmsadmin.modules.sso.utils.LoginTypeEnum;
import com.ics.cmsadmin.modules.sso.utils.SsoContants;
import com.ics.cmsadmin.modules.sso.utils.SsoUtils;
import com.ics.cmsadmin.modules.system.emums.RegisterKeyValueEnum;
import com.ics.cmsadmin.modules.system.service.RegisterService;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.velocity.VelocityContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.function.Function;

/**
 * Created by 666666 on 2018/8/25.
 */
@RestController
@RequestMapping("/oauth2")
public class LoginController {

    @Resource
    private CmsAdminWebLoginHandler cmsAdminWebLoginHandler;
    @Resource
    private WechatCodeLoginHandler wechatCodeLoginHandler;
    @Resource
    private UserService userService;
    @Resource
    private RegisterService registerService;
    @RequestMapping("/login")
    public ApiResponse login(HttpServletRequest request, HttpServletResponse response) {
        String loginType = request.getParameter(SsoContants.LOGIN_TYPE);
        LoginTypeEnum loginTypeEnum = LoginTypeEnum.valueOfType(loginType);
        if (loginTypeEnum == null){
            throw new CmsException(ApiResultEnum.LOGIN_TYPE_ERROR);
        }
        LoginInfo loginInfo = null;
        switch (loginTypeEnum){
            case CMS_ADMIN_WEB:
                loginInfo = cmsAdminWebLoginHandler.dealWithLogin(request, response, loginTypeEnum);
                break;
            case CMS_ADMIN_WEB_TOKEN:
                loginInfo = cmsAdminWebLoginHandler.dealWithLogin(request, response, loginTypeEnum);
                break;
            case WECHAT_CODE_LOGIN:
                loginInfo = wechatCodeLoginHandler.dealWithLogin(request, response, loginTypeEnum);
            default:    // never go here
                break;
        }
        if (loginInfo == null){
            return ApiResponse.getResponse(ApiResultEnum.LOGIN_FAILED);
        }else {
            return ApiResponse.getDefaultResponse(loginInfo);
        }
    }

    @GetMapping("/checkLogin")
    public void checkLogin(HttpServletRequest request, HttpServletResponse response) {
        LoginInfo loginInfo = SsoUtils.getLoginUser(request);
        if (loginInfo == null){
            HttpUtils.setJsonDataResponse(response, ApiResponse.getResponse(ApiResultEnum.LOGIN_PAST_DUE), 403);
        }
    }

    @PostMapping("/sendResetPasswordEmail")
    public ApiResponse sendResetPasswordEmail(String email){
        // 限制同一个邮箱多次发送重置密码
        String emailReidKey = String.format("sendResetPasswordEmail:%s", email);
        if (StringUtils.isNotBlank(RedisUtils.get(emailReidKey))){
            return new ApiResponse("找回密码邮件已经发送到邮箱" + email + "，请查收");
        }
        SysUser one = userService.findOne(SysUser.builder().email(email).status(Constants.ENABLE_STATUS).build());
        if (one == null){
            return new ApiResponse("没找到该用户");
        }
        String code = Tools.randomString(6);
        RedisUtils.set(emailReidKey, code, 1800);

        Map<String, Object> params = new HashMap<>();
        params.put("userName", one.getLoginName());
        params.put("code", code);
        MailUtils.sendEmail(email, "重置爱课塾密码", VelocityUtils.getContent("vm/resetPasswordEmail.vm", params));
        return new ApiResponse(true);
    }

    @PostMapping("/resetPasswordEmail")
    public ApiResponse resetPasswordEmail(String email, String code) {
        String emailReidKey = String.format("sendResetPasswordEmail:%s", email);
        String redisValue = RedisUtils.get(emailReidKey);
        if (StringUtils.isBlank(redisValue)){
            return new ApiResponse("请先发送忘记密码邮件");
        }
        if (!StringUtils.equalsIgnoreCase(redisValue, code)){
            return new ApiResponse("验证码不正确");
        }
        SysUser one = userService.findOne(SysUser.builder().email(email).status(Constants.ENABLE_STATUS).build());
        if (one == null){
            return new ApiResponse("没找到该用户");
        }
        userService.resetPassword(one.getUserId());
        RedisUtils.delete(emailReidKey);
        return new ApiResponse(true);
    }
}
